#include <os/lock.h>
#include <os/sched.h>
#include <os/list.h>
#include <atomic.h>

mutex_lock_t mlocks[LOCK_NUM];

void init_locks(void)
{
    /* TODO: [p2-task2] initialize mlocks */

}

void spin_lock_init(spin_lock_t *lock)
{
    /* TODO: [p2-task2] initialize spin lock */
}

int spin_lock_try_acquire(spin_lock_t *lock)
{
    /* TODO: [p2-task2] try to acquire spin lock */
    return 0;
}

void spin_lock_acquire(spin_lock_t *lock)
{
    /* TODO: [p2-task2] acquire spin lock */
}

void spin_lock_release(spin_lock_t *lock)
{
    /* TODO: [p2-task2] release spin lock */
}

int do_mutex_lock_init(int key)
{
    /* TODO: [p2-task2] initialize mutex lock */
    mlocks[key].block_queue.next = &mlocks[key].block_queue;
    mlocks[key].block_queue.prev = &mlocks[key].block_queue;
    // 初始化，锁需要开启。
    mlocks[key].lock.status = UNLOCKED;
    mlocks[key].key = 42;
    return 0;
}

void do_mutex_lock_acquire(int mlock_idx)
{
    /* TODO: [p2-task2] acquire mutex lock */
    if (mlocks[mlock_idx].lock.status == LOCKED)
        do_block(&current_running->list, &mlocks[mlock_idx].block_queue);
    else
        mlocks[mlock_idx].lock.status = LOCKED;
        current_running->locks[current_running->locknum++] = mlock_idx;
}

void do_mutex_lock_release(int mlock_idx)
{
    /* TODO: [p2-task2] release mutex lock */
    current_running->locknum--;
    if(mlocks[mlock_idx].block_queue.next == &mlocks[mlock_idx].block_queue || mlocks->block_queue.next == NULL)
    {
        mlocks[mlock_idx].lock.status = UNLOCKED;
    }
    else
        do_unblock(&mlocks[mlock_idx].block_queue);
}
int count = 0;
int mutex_init(void)
{
    do_mutex_lock_init(count);
    return count;
}

int mutex_lock(int handle)
{
    do_mutex_lock_acquire(count);
    return count;
}

int mutex_unlock(int handle)    
{
    do_mutex_lock_release(count);
    return count;
}